package com.yj;

import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class JobDemo {
    private Logger logger = LoggerFactory.getLogger(getClass());

    private final AtomicInteger counts = new AtomicInteger();

    @Scheduled(fixedDelay = 5000)//间隔时间毫秒，以调用完成时间开始计算
    @SchedulerLock(name = "JobDemo.job1", lockAtMostFor = "2s", lockAtLeastFor = "1s")//锁的名字、最大时间、最小时间
    public void job1() {
        logger.info("[job1][定时第 ({}) 次执行]", counts.incrementAndGet());
    }

    @Scheduled(fixedRate = 5000)//间隔时间毫秒，以调用开始时间开始计算
    @SchedulerLock(name = "JobDemo.job2", lockAtMostFor = "2s", lockAtLeastFor = "1s")
    public void job2() {
        logger.info("[job2][定时第 ({}) 次执行]", counts.incrementAndGet());
    }

    @Scheduled(cron = "0/10 * * * * ?")//cron表达式，秒 分 时 日 月 周，以调用完成时间开始计算
    @SchedulerLock(name = "JobDemo.job3", lockAtMostFor = "2m", lockAtLeastFor = "1m")
    public void job3() {
        logger.info("[job3][定时第 ({}) 次执行。。。。]", counts.incrementAndGet());
        try {
            // 通过修改执行时间进行测试可以看出：
            // 1、执行开始会将分布式锁的到期时间设定为最大时间。
            // 2、执行结束如果没有超过最小时间会将到期时间改为最小时间，如果超过最小时间就以执行结束时间为到期时间（即立即释放锁）
            TimeUnit.SECONDS.sleep(90);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        logger.info("[job3][定时第 ({}) 次执行结束]", counts.incrementAndGet());
    }
}
